package fr.obsmip.sedoo.client.ui;

import java.util.Iterator;
import java.util.List;

import org.gwtbootstrap3.client.ui.Popover;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.Widget;

import fr.obsmip.sedoo.client.message.Message;
import fr.obsmip.sedoo.client.misc.DateTools;
import fr.obsmip.sedoo.shared.domain.SearchCriteriaDTO;
import fr.sedoo.commons.client.message.CommonMessages;
import fr.sedoo.commons.client.util.StringUtil;
import fr.sedoo.commons.client.widget.DialogBoxTools;
import fr.sedoo.commons.client.widget.editing.ValidationAlert;
import fr.sedoo.commons.client.widget.map.impl.SingleAreaSelectorWidget;
import fr.sedoo.commons.shared.domain.GeographicBoundingBoxDTO;
import fr.sedoo.metadata.client.ui.editablechosen.MultipleValueTextBox;
import fr.sedoo.metadata.client.ui.widget.date.Iso19115DateBox;

public class MetadataSearchViewImpl extends AbstractSection implements MetadataSearchView
{

	private static MetadataSearchViewImplUiBinder uiBinder = GWT.create(MetadataSearchViewImplUiBinder.class);

	interface MetadataSearchViewImplUiBinder extends UiBinder<Widget, MetadataSearchViewImpl>
	{
	}

	private static final String UNSELECTED_ID = "NONE";

	@UiField
	SingleAreaSelectorWidget mapSelector;

	@UiField
	MultipleValueTextBox keywords;

	@UiField
	Button searchButton;

	@UiField
	Button resetButton;

	@UiField
	RadioButton anyKeyword;

	@UiField
	RadioButton allKeyword;

	@UiField
	ListBox observatory;

	@UiField
	Iso19115DateBox startDate;

	@UiField
	Iso19115DateBox endDate;

	@UiField
	Popover startDatePopover;

	@UiField
	Popover endDatePopover;
	
	@UiField
	CheckBox observatoryType;
	
	@UiField
	CheckBox experimentalSiteType;
	
	@UiField
	CheckBox datasetType;

	private Presenter presenter;

	private String observatoryToSelect;

	public MetadataSearchViewImpl()
	{
		super();
		initWidget(uiBinder.createAndBindUi(this));
		applyCommonStyle();
		keywords.setSize("600px", "50px");
		reset();
		mapSelector.enableEditMode();
	}

	private void reset()
	{
		// On initialise avec une boite vide afin d'afficher une carte du monde
		GeographicBoundingBoxDTO geographicBoundingBoxDTO = new GeographicBoundingBoxDTO();
		mapSelector.setGeographicBoundingBoxDTO(geographicBoundingBoxDTO);
		keywords.reset();
		allKeyword.setValue(true);

		if (observatory.getItemCount()>0)
		{
			observatory.setSelectedIndex(0);
		}

		startDate.setValue(null);
		endDate.setValue(null);
		observatoryType.setValue(false);
		experimentalSiteType.setValue(false);
		datasetType.setValue(false);
	}

	@UiHandler("searchButton")
	void onSearchButtonClicked(ClickEvent event)
	{
		SearchCriteriaDTO criteria = flush();
		if (criteria.isEmpty())
		{
			DialogBoxTools.modalAlert(CommonMessages.INSTANCE.error(), Message.INSTANCE.metadataSearchingEmptyCriteria());
			return;
		}

		List<ValidationAlert> validate = criteria.validate();
		if (validate.isEmpty() == false)
		{
			DialogBoxTools.popUpScrollable(CommonMessages.INSTANCE.error(), ValidationAlert.toHTML(validate), DialogBoxTools.HTML_MODE);
			return;
		}

		presenter.search(criteria);
	}

	private SearchCriteriaDTO flush()
	{
		SearchCriteriaDTO criteria = new SearchCriteriaDTO();
		criteria.setBoundingBoxDTO(mapSelector.getGeographicBoundingBoxDTO());
		criteria.setKeywords(keywords.getValues());
		if (allKeyword.getValue() == true)
		{
			criteria.setKeywordsLogicalLink(SearchCriteriaDTO.AND);
		} else
		{
			criteria.setKeywordsLogicalLink(SearchCriteriaDTO.OR);
		}

		if (startDate.getValue() == null)
		{
			criteria.setEndDate(null);
		} else
		{
			criteria.setStartDate(DateTools.getRBVDateFormat().format(startDate.getValue()));
		}

		if (endDate.getValue() == null)
		{
			criteria.setEndDate(null);
		} else
		{
			criteria.setEndDate(DateTools.getRBVDateFormat().format(endDate.getValue()));
		}
		if (observatory.getSelectedIndex()>0)
		{
			criteria.setObservatory(observatory.getValue(observatory.getSelectedIndex()));
		}
		
		criteria.setIncludesExperimentalSites(experimentalSiteType.getValue());
		criteria.setIncludesObservatories(observatoryType.getValue());
		criteria.setIncludesDatasets(datasetType.getValue());
		
		return criteria;
	}

	@UiHandler("resetButton")
	void onResetButtonClicked(ClickEvent event)
	{
		reset();
	}

	@Override
	public void setPresenter(Presenter presenter)
	{
		this.presenter = presenter;
	}

	@Override
	public void update(SearchCriteriaDTO criteria)
	{
		reset();
		keywords.setValues(criteria.getKeywords());
		if (criteria.getKeywordsLogicalLink().compareTo(SearchCriteriaDTO.AND) == 0)
		{
			allKeyword.setValue(true);
			anyKeyword.setValue(false);
		} else
		{
			allKeyword.setValue(false);
			anyKeyword.setValue(true);
		}
		if (criteria.getBoundingBoxDTO().validate().isEmpty())
		{
			mapSelector.setGeographicBoundingBoxDTO(criteria.getBoundingBoxDTO());
		}

		if (criteria.getStartDate() == null)
		{
			startDate.setValue(null);
		} else
		{
			startDate.setValue(DateTools.getRBVDateFormat().parse(criteria.getStartDate()));
		}

		if (criteria.getEndDate() == null)
		{
			endDate.setValue(null);
		} else
		{
			endDate.setValue(DateTools.getRBVDateFormat().parse(criteria.getEndDate()));
		}
		
		experimentalSiteType.setValue(criteria.isIncludesExperimentalSites());
		observatoryType.setValue(criteria.isIncludesObservatories());
		datasetType.setValue(criteria.isIncludesDatasets());
		
		if (StringUtil.isNotEmpty(criteria.getObservatory())) 
		{
			observatoryToSelect = criteria.getObservatory();
		}

	}

	@Override
	public void setObservatories(List<String> values)
	{
		observatory.clear();
		observatory.addItem(Message.INSTANCE.selectItem(), UNSELECTED_ID);
		Iterator<String> iterator = values.iterator();
		while (iterator.hasNext())
		{
			String aux = iterator.next();
			observatory.addItem(aux, aux);
		}
		if (StringUtil.isNotEmpty(observatoryToSelect))
		{
			for (int i=0; i < observatory.getItemCount();i++)
			{
				if (observatory.getItemText(i).compareToIgnoreCase(observatoryToSelect)==0)
				{
					observatory.setItemSelected(i, true);
					observatoryToSelect="";
					break;
				}
			}
		}

	}

}
